/**
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-12-03 14:14:47
 * Copyright (c) 2015- joysuch-版权所有
 */

package com.joysuch.wwyt.bp.service.impl;

import com.joysuch.wwyt.bp.bean.BpStorageTankAddBean;
import com.joysuch.wwyt.bp.bean.BpStorageTankBean;
import com.joysuch.wwyt.bp.entity.BpDeviceFacilityCollection;
import com.joysuch.wwyt.bp.entity.BpMonitoringPointRel;
import com.joysuch.wwyt.bp.entity.BpStorageTank;
import com.joysuch.wwyt.bp.entity.BpStorageTankArea;
import com.joysuch.wwyt.bp.enums.DeviceFacilityTypes;
import com.joysuch.wwyt.bp.repository.BpMonitoringPointRelDao;
import com.joysuch.wwyt.bp.repository.BpStorageTankAreaDao;
import com.joysuch.wwyt.bp.repository.BpStorageTankDao;
import com.joysuch.wwyt.bp.service.BpDeviceFacilityCollectionService;
import com.joysuch.wwyt.bp.service.BpStorageTankService;
import com.joysuch.wwyt.core.common.util.StringUtil;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.joysuch.wwyt.mh.bean.MhMonitoringPointBean;
import com.joysuch.wwyt.mh.entity.MhMonitoringPoint;
import com.joysuch.wwyt.mh.repository.MhMajorHazardDao;
import com.joysuch.wwyt.mh.repository.MhMonitoringPointDao;
import com.joysuch.wwyt.mh.service.MhMonitoringPointService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static java.util.Collections.EMPTY_LIST;

@Service
@Transactional
public class BpStorageTankServiceImpl implements BpStorageTankService {

    @Autowired
    private BpStorageTankAreaDao bpStorageTankAreaDao;
    @Autowired
    private BpMonitoringPointRelDao relDao;
    @Autowired
    private BpStorageTankDao dao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;
    @Autowired
    private BpDeviceFacilityCollectionService bpDeviceFacilityCollectionService;
    @Autowired
    private MhMajorHazardDao mhMajorHazardDao;
    @Autowired
    private MhMonitoringPointDao mhMonitoringPointDao;
    @Autowired
    private MhMonitoringPointService mhMonitoringPointService;

    @Override
    public String add(BpStorageTankAddBean s) throws Exception {
        String errorMessage = "";
        BpStorageTank b = new BpStorageTank();
        b.setArch(s.getArch());
        b.setBelongGroupCode(s.getBelongGroupCode());
        // b.setBpStorageTankArea(s.getBpStorageTankAreaId());
        b.setBpStorageTankArea(s.getBpStorageTankArea());
//        if (StringUtils.isEmpty(s.getUniCode())) {
//            b.setCode(bizCodeGeneratorFacade.chuGuan());
//            b.setUniCode(b.getCode());
//        } else {
//            Assert.isTrue(dao.findByCode(s.getUniCode()).isEmpty(), "统一编码" + s.getUniCode() + "已经存在");
//            b.setUniCode(s.getUniCode());
//            b.setCode(s.getUniCode());
//        }
        Assert.notNull(s.getUniCode(), "编号不能为空");
        b.setCode(s.getUniCode());
        b.setUniCode(s.getUniCode());
        BpStorageTank tank = dao.findByUniCode(b.getUniCode());
        if (tank != null) {
            throw new IllegalArgumentException("编号" + b.getUniCode() + "已存在");
        }
        b.setCofferdamArea(s.getCofferdamArea());
        b.setCommissioningDate(s.getCommissioningDate());
        // b.setUniCode(bizCodeGeneratorFacade.chuGuan());
        // b.setCreateBy(s.getCreateBy());
        // b.setCreateTime(s.getCreateTime());
        b.setDangerousControlSystem(s.getDangerousControlSystem());
        b.setDesignLiquidLevel(s.getDesignLiquidLevel());
        b.setDesignPressure(s.getDesignPressure());
        b.setDesignStorageVolume(s.getDesignStorageVolume());
        b.setHasCofferdam(s.getHasCofferdam());
        b.setInOutMethod(s.getInOutMethod());
        b.setIsDangerousTank(s.getIsDangerousTank());
        b.setIsFormDangerousTank(s.getIsFormDangerousTank());
        b.setIsFormMajorHazard(s.getIsFormMajorHazard());
        b.setIsPressureContainer(s.getIsPressureContainer());
        b.setIsProvideFireWaterMonitor(s.getIsProvideFireWaterMonitor());
        b.setIsProvideHeatPreservation(s.getIsProvideHeatPreservation());
        b.setIsProvideTorch(s.getIsProvideTorch());
        b.setIsSetAutomaticSpray(s.getIsSetAutomaticSpray());
        b.setLiquidLevelAlarmHigh1(s.getLiquidLevelAlarmHigh1());
        b.setLiquidLevelAlarmHigh2(s.getLiquidLevelAlarmHigh2());
        b.setLiquidLevelAlarmLow1(s.getLiquidLevelAlarmLow1());
        b.setLiquidLevelAlarmLow2(s.getLiquidLevelAlarmLow2());
        b.setLiquidometerType(s.getLiquidometerType());
        if (s.getLocation() != null && !"".equals(s.getLocation())) {
            b.setLocation(s.getLocation());
        }
        b.setLocationCategory(s.getLocationCategory());
        b.setMaterial(s.getMaterial());
        b.setName(s.getName());
        b.setOpPressureHighValue(s.getOpPressureHighValue());
        b.setOpPressureLowValue(s.getOpPressureLowValue());
        b.setOpTemperatureHighValue(s.getOpTemperatureHighValue());
        b.setOpTemperatureLowValue(s.getOpTemperatureLowValue());
        b.setPressureLevel(s.getPressureLevel());
        b.setSafeDevice(s.getSafeDevice());
        b.setType(s.getType());
        b.setUpdateBy(s.getUpdateBy());
        b.setUpdateTime(s.getUpdateTime());
        b.setVolume(s.getVolume());
        setWorkTemperatureAndPressureInfo(s, b);

        if (s.getMhMajorHazard() != null) {
            b.setMhMajorHazard(mhMajorHazardDao.getOne(s.getMhMajorHazard()));
        }

        BpStorageTank save = dao.save(b);

        List<Long> pointId = s.getPointId();
        if (pointId != null) {
            for (Long aLong : pointId) {
                String str = mhMonitoringPointService.checkMhMointPoint(aLong, save.getId());
                if (StringUtils.isNotBlank(str)) {
                    errorMessage = errorMessage + ' ' + str;
                }
                if (s.getExcelFlag() == null && StringUtils.isBlank(errorMessage) || (StringUtils.isBlank(errorMessage) && s.getExcelFlag() != null && s.getExcelFlag().intValue() == 1)) {
                    BpMonitoringPointRel bpMonitoringPointRel = new BpMonitoringPointRel();
                    bpMonitoringPointRel.setRefType("store_tank");
                    bpMonitoringPointRel.setRefId(save.getId());
                    bpMonitoringPointRel.setMonitoringPointId(aLong);
                    relDao.save(bpMonitoringPointRel);
                }
            }
        }
        if (s.getExcelFlag() == null && StringUtils.isBlank(errorMessage) || (StringUtils.isBlank(errorMessage) && s.getExcelFlag() != null && s.getExcelFlag().intValue() == 1)) {
            addOrUpdateDeviceFacilityCollection(save, pointId);
        }
        return errorMessage;
    }

    private void addOrUpdateDeviceFacilityCollection(BpStorageTank save, List<Long> pointId) {
        // 保存到集中统一的表中
        BpDeviceFacilityCollection device = bpDeviceFacilityCollectionService.addOrUpdateOtherDevice(
                DeviceFacilityTypes.CHU_GUAN, save.getId(), save.getCode(), save.getName(), null,
                save.getMhMajorHazard() == null ? null : save.getMhMajorHazard().getId(), save.getLocation());
        // 绑定监测点
        bpDeviceFacilityCollectionService.bindDeviceAndMonitorPointsByIds(device, pointId);

    }

    //判断监测点是否被其他储罐绑定
    private void checkTankPoint(Long pointId) {
        List<BpMonitoringPointRel> aList = relDao.findByRefTypeAndMonitoringPointId("store_tank", pointId);
        if (aList.size() > 1) {
            throw new IllegalArgumentException("该监测点已经绑定其他储罐");
        }
    }

    @Override
    public String update(BpStorageTankAddBean s) throws Exception {
        String errorMessage = "";
        BpStorageTank b = dao.findById(s.getId()).get();
        relDao.deleteByRefTypeAndRefId("store_tank", s.getId());
        Assert.notNull(s.getUniCode(), "编号不能为空");
        Assert.isTrue(dao.countOfCodeExcludeId(s.getUniCode(), s.getId()) == 0,
                String.format("编号%s已经存在", s.getUniCode()));
        b.setCode(s.getUniCode());
        b.setUniCode(s.getUniCode());
        b.setArch(s.getArch());
        b.setCofferdamArea(s.getCofferdamArea());
        b.setCommissioningDate(s.getCommissioningDate());
        b.setDangerousControlSystem(s.getDangerousControlSystem());
        b.setDesignLiquidLevel(s.getDesignLiquidLevel());
        b.setDesignPressure(s.getDesignPressure());
        b.setDesignStorageVolume(s.getDesignStorageVolume());
        b.setHasCofferdam(s.getHasCofferdam());
        b.setInOutMethod(s.getInOutMethod());
        b.setIsDangerousTank(s.getIsDangerousTank());
        b.setIsFormDangerousTank(s.getIsFormDangerousTank());
        b.setIsFormMajorHazard(s.getIsFormMajorHazard());
        b.setIsPressureContainer(s.getIsPressureContainer());
        b.setIsProvideFireWaterMonitor(s.getIsProvideFireWaterMonitor());
        b.setIsProvideHeatPreservation(s.getIsProvideHeatPreservation());
        b.setIsProvideTorch(s.getIsProvideTorch());
        b.setIsSetAutomaticSpray(s.getIsSetAutomaticSpray());
        b.setLiquidLevelAlarmHigh1(s.getLiquidLevelAlarmHigh1());
        b.setLiquidLevelAlarmHigh2(s.getLiquidLevelAlarmHigh2());
        b.setLiquidLevelAlarmLow1(s.getLiquidLevelAlarmLow1());
        b.setLiquidLevelAlarmLow2(s.getLiquidLevelAlarmLow2());
        b.setLiquidometerType(s.getLiquidometerType());
        b.setLocation(s.getLocation());
        b.setLocationCategory(s.getLocationCategory());
        b.setMaterial(s.getMaterial());
        b.setName(s.getName());
        b.setOpPressureHighValue(s.getOpPressureHighValue());
        b.setOpPressureLowValue(s.getOpPressureLowValue());
        b.setOpTemperatureHighValue(s.getOpTemperatureHighValue());
        b.setOpTemperatureLowValue(s.getOpTemperatureLowValue());
        b.setPressureLevel(s.getPressureLevel());
        b.setSafeDevice(s.getSafeDevice());
        b.setType(s.getType());
        b.setVolume(s.getVolume());

        setWorkTemperatureAndPressureInfo(s, b);

        if (s.getMhMajorHazard() != null) {
            b.setMhMajorHazard(mhMajorHazardDao.getOne(s.getMhMajorHazard()));
        }

        BpStorageTank save = dao.save(b);
        List<Long> pointId = s.getPointId();
        if (pointId != null) {
            for (Long aLong : pointId) {
                String str = mhMonitoringPointService.checkMhMointPoint(aLong, save.getId());
                if (StringUtils.isNotBlank(str)) {
                    errorMessage = errorMessage + " " + str;
                }
                if (s.getExcelFlag() == null && StringUtils.isBlank(errorMessage) || (StringUtils.isBlank(errorMessage) && s.getExcelFlag() != null && s.getExcelFlag().intValue() == 1)) {
                    BpMonitoringPointRel bpMonitoringPointRel = new BpMonitoringPointRel();
                    bpMonitoringPointRel.setRefType("store_tank");
                    bpMonitoringPointRel.setRefId(save.getId());
                    bpMonitoringPointRel.setMonitoringPointId(aLong);
                    if (s.getExcelFlag() == null && StringUtils.isBlank(errorMessage) || (StringUtils.isBlank(errorMessage) && s.getExcelFlag() != null && s.getExcelFlag().intValue() == 1)) {
                        relDao.save(bpMonitoringPointRel);
                    }
                }
            }
        }
        if (s.getExcelFlag() == null && StringUtils.isBlank(errorMessage) || (StringUtils.isBlank(errorMessage) && s.getExcelFlag() != null && s.getExcelFlag().intValue() == 1)) {
            addOrUpdateDeviceFacilityCollection(save, pointId);
        }
        return errorMessage;
    }

    /**
     * @param s
     * @param b
     */
    protected void setWorkTemperatureAndPressureInfo(BpStorageTankAddBean s, BpStorageTank b) {
        try {
            if (s.getWorkPressureHighRange() != null) {
                String[] split = s.getWorkPressureHighRange();
                if (StringUtils.isNotBlank(split[0])) {
                    b.setWorkPressureLowValue(Float.parseFloat(split[0]));
                }
                if (StringUtils.isNotBlank(split[1])) {
                    b.setWorkPressureHighValue(Float.parseFloat(split[1]));
                }
                if (s.getWorkPressureHighValue() != null && s.getWorkPressureLowValue() != null) {
                    Assert.isTrue(s.getWorkPressureHighValue() >= s.getWorkPressureLowValue(), "工作压力区间，上限压力必须大于等于下限压力");
                }
            }
            if (s.getWorkTemperatureRange() != null) {
                String[] split1 = s.getWorkTemperatureRange();
                if (StringUtils.isNotBlank(split1[0])) {
                    b.setWorkTemperatureLowValue(Float.parseFloat(split1[0]));
                }
                if (StringUtils.isNotBlank(split1[1])) {
                    b.setWorkTemperatureHighValue(Float.parseFloat(split1[1]));
                }
                if (s.getWorkTemperatureHighValue() != null && s.getWorkTemperatureLowValue() != null) {
                    Assert.isTrue(s.getWorkTemperatureHighValue() >= s.getWorkTemperatureLowValue(),
                            "工作区间温度，上限温度必须大于等于下限温度");
                }
            }

        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("工作区间温度，工作压力区间只能填写数字", e);
        } catch (Exception e) {
            throw e;
        }
    }

    @Override
    public Page<BpStorageTank> findByPage(Pageable page) {
        return dao.findAll(page);
    }

    @Override
    public void delete(Long id) {
        relDao.deleteByRefTypeAndRefId("store_tank", id);
        dao.deleteById(id);
        bpDeviceFacilityCollectionService.delteByDeviceTypeAndDeviceId(DeviceFacilityTypes.CHU_GUAN, id);
    }

    @Override
    public BpStorageTankBean findById(Long id) {

        Optional<BpStorageTank> tankOptional = dao.findById(id);
        BpStorageTankBean b = new BpStorageTankBean();
        if (tankOptional.isPresent()) {
            BpStorageTank s = tankOptional.get();
            b.setArch(s.getArch());
            b.setCofferdamArea(s.getCofferdamArea());
            b.setCommissioningDate(s.getCommissioningDate());
            b.setDangerousControlSystem(s.getDangerousControlSystem());
            b.setDesignLiquidLevel(s.getDesignLiquidLevel());
            b.setDesignPressure(s.getDesignPressure());
            b.setDesignStorageVolume(s.getDesignStorageVolume());
            b.setHasCofferdam(s.getHasCofferdam());
            b.setInOutMethod(s.getInOutMethod());
            b.setIsDangerousTank(s.getIsDangerousTank());
            b.setIsFormDangerousTank(s.getIsFormDangerousTank());
            b.setIsFormMajorHazard(s.getIsFormMajorHazard());
            b.setIsPressureContainer(s.getIsPressureContainer());
            b.setIsProvideFireWaterMonitor(s.getIsProvideFireWaterMonitor());
            b.setIsProvideHeatPreservation(s.getIsProvideHeatPreservation());
            b.setIsProvideTorch(s.getIsProvideTorch());
            b.setIsSetAutomaticSpray(s.getIsSetAutomaticSpray());
            b.setLiquidLevelAlarmHigh1(s.getLiquidLevelAlarmHigh1());
            b.setLiquidLevelAlarmHigh2(s.getLiquidLevelAlarmHigh2());
            b.setLiquidLevelAlarmLow1(s.getLiquidLevelAlarmLow1());
            b.setLiquidLevelAlarmLow2(s.getLiquidLevelAlarmLow2());
            b.setLiquidometerType(s.getLiquidometerType());
            b.setLocation(s.getLocation());
            b.setLocationCategory(s.getLocationCategory());
            b.setMaterial(s.getMaterial());
            b.setName(s.getName());
            b.setOpPressureHighValue(s.getOpPressureHighValue());
            b.setOpPressureLowValue(s.getOpPressureLowValue());
            b.setOpTemperatureHighValue(s.getOpTemperatureHighValue());
            b.setOpTemperatureLowValue(s.getOpTemperatureLowValue());
            b.setPressureLevel(s.getPressureLevel());
            b.setSafeDevice(s.getSafeDevice());
            b.setType(s.getType());
            b.setUniCode(s.getUniCode());
            b.setVolume(s.getVolume());
            b.setId(s.getId());
            Float workPressureHighValue = s.getWorkPressureHighValue();
            Float workPressureLowValue = s.getWorkPressureLowValue();
            Float workTemperatureHighValue = s.getWorkTemperatureHighValue();
            Float workTemperatureLowValue = s.getWorkTemperatureLowValue();
            b.setWorkPressureHighRange(new String[]{StringUtil.escapeNull(workPressureLowValue),
                    StringUtil.escapeNull(workPressureHighValue)});
            b.setWorkTemperatureRange(new String[]{StringUtil.escapeNull(workTemperatureLowValue),
                    StringUtil.escapeNull(workTemperatureHighValue)});
            if (s.getMhMajorHazard() != null) {
                b.setMhMajorHazard(s.getMhMajorHazard().getId());
                b.setMhMajorHazardName(s.getMhMajorHazard().getName());
            }
            b.setBpStorageTankAreaId(s.getBpStorageTankArea());
            Optional<BpStorageTankArea> areaOptional = bpStorageTankAreaDao.findById(s.getBpStorageTankArea());
            if (areaOptional.isPresent()) {
                BpStorageTankArea area = areaOptional.get();
                b.setBpStorageTankAreaCode(area.getCode());
                b.setBpStorageTankAreaName(area.getName());
            }

            ArrayList<MhMonitoringPointBean> objects = new ArrayList<>();
            List<BpMonitoringPointRel> m = relDao.findByRefTypeAndRefId("store_tank", id);
            for (BpMonitoringPointRel rel : m) {
                Optional<MhMonitoringPoint> pointOptional = mhMonitoringPointDao.findById(rel.getMonitoringPointId());
                if (pointOptional.isPresent()) {
                    MhMonitoringPoint one = pointOptional.get();
                    MhMonitoringPointBean mhMonitoringPointBean = new MhMonitoringPointBean();
                    mhMonitoringPointBean.setId(one.getId());
                    mhMonitoringPointBean.setName(one.getName());
                    mhMonitoringPointBean.setRealtimeValue(one.getRealtimeValue());
                    mhMonitoringPointBean.setPointCode(one.getPointCode());
                    mhMonitoringPointBean.setMinitoringTypeName(one.getMhMonitoringType().getName());
                    objects.add(mhMonitoringPointBean);
                }

            }
            if (objects.isEmpty()) {
                b.setMhMonitoringPointBean(EMPTY_LIST);
            }
            b.setMhMonitoringPointBean(objects);
        }
        return b;
    }

    @Override
    public BpStorageTank findByUniCode(String uniCode) {
        return dao.findByUniCode(uniCode);
    }

}
